package br.uece.ativcomplementares.business;

import java.util.List;

import javax.persistence.NoResultException;

import br.uece.ativcomplementares.dao.UsuarioDao;
import br.uece.ativcomplementares.dto.EmailDto;
import br.uece.ativcomplementares.entity.Aluno;
import br.uece.ativcomplementares.entity.Professor;
import br.uece.ativcomplementares.entity.Usuario;
import br.uece.ativcomplementares.enums.PerfilEnum;
import br.uece.ativcomplementares.exceptions.BusinessException;
import br.uece.ativcomplementares.services.EmailService;
import br.uece.ativcomplementares.utils.GeradorSenha;

public class UsuarioBO extends Business<Usuario> {
	UsuarioDao usuarioDao;
	
	EmailService emailService;
	
	public UsuarioBO(UsuarioDao dao, EmailService emailService) {
		super(dao);
		this.usuarioDao = dao;
		this.emailService = emailService;
	}
	
	public Usuario efetuarLogin(String login, String senha) {
		try {
			return usuarioDao.buscarUsuario(login, senha);
		} catch (NoResultException e) {
			throw new BusinessException("Usuário ou senha inválido.");
		}	
	}
	
	public void cadastrarAluno(Aluno aluno) {
		Usuario usuario = new Usuario(PerfilEnum.Aluno);
		
		usuario.setLogin(aluno.getMatricula());
		usuario.setSenha(GeradorSenha.getSenhaRandomica());
		usuario.setAluno(aluno);
		
		validarAluno(usuario);
		
		usuarioDao.incluir(usuario);
		
		enviarEmailNovoUsuario(usuario);
	}
	
	private void enviarEmailNovoUsuario(Usuario usuario) {
		EmailDto email = new EmailDto();
		email.setAssunto("Novo usuário SISAC");
		email.setDestinatarios(usuario.getPerfil() == PerfilEnum.Aluno ? usuario.getAluno().getEmail() : usuario.getProfessor().getEmail());
		
		StringBuilder corpo = new StringBuilder()
			.append("Foi criado um novo usuário no SISAC com matrícula <b>")
			.append(usuario.getPerfil() == PerfilEnum.Aluno ? usuario.getAluno().getMatricula() : usuario.getProfessor().getMatricula())
			.append("</b> e senha <b>")
			.append(usuario.getSenha()).append("</b>");
		
		email.setCorpo(corpo.toString());
		
		emailService.enviarEmail(email);
	}
	
	public void cadastrarProfessor(Professor professor) {
		Usuario usuario = new Usuario(PerfilEnum.Professor);
		
		usuario.setLogin(professor.getEmail());
		usuario.setSenha(GeradorSenha.getSenhaRandomica());
		usuario.setProfessor(professor);
		
		validarProfessor(usuario);
		
		usuarioDao.incluir(usuario);
		
		enviarEmailNovoUsuario(usuario);
	}
	
	@Override
	public void atualizar(Usuario usuario) {
		if (usuario.getPerfil() == PerfilEnum.Professor && usuario.getProfessor() != null) {
			validarProfessor(usuario);
		} else if (usuario.getPerfil() == PerfilEnum.Aluno && usuario.getAluno() != null) {
			validarAluno(usuario);
		}
		
		super.atualizar(usuario);
	}
	
	private void validarAluno(Usuario usuario) {
		try {
			Aluno alunoPersistido = usuarioDao.buscarAlunoComMatricula(usuario.getAluno().getMatricula());
			
			if (alunoPersistido != null  
					&& (usuario.getAluno().getId() == null || usuario.getAluno().getId() != alunoPersistido.getId())) {
				throw new BusinessException("Existe aluno cadastro com a matricula informada.");
			}
		} catch (NoResultException e) {
			// Continua
		}
	}
	
	private void validarProfessor(Usuario usuario) {
		try {
			if (usuario.getProfessor() == null) {
				throw new IllegalArgumentException("Objeto professor está nulo.");
			}
			
			Professor professorPersistido = usuarioDao.buscarProfessorComEmail(usuario.getProfessor().getEmail());
			if (professorPersistido != null  
					&& (usuario.getProfessor().getId() == null || usuario.getProfessor().getId() != professorPersistido.getId())) {
				throw new BusinessException("Existe professor cadastrado com o E-mail informado.");
			}
		} catch (NoResultException e) {
			// Continua
		}
	}
	
	public List<Usuario> listarTodosProfessores() {
		return usuarioDao.listarTodosProfessores();
	}
	
	public List<Usuario> listarTodosAlunos() {
		return usuarioDao.listarTodosAlunos();
	}
	
	public List<Aluno> buscarAlunosComMatriculaOuNome(String query) {
		return usuarioDao.buscarAlunoComMatriculaOuNome(query);
	}
}
